package com.github.llyb120.test;

import com.github.llyb120.mugen.PluginRunner;
import com.github.llyb120.workflow.WorkflowHolder;
import com.github.llyb120.workflow.adapter.DealerAdapter;
import com.github.llyb120.workflow.adapter.MemoryDealer;
import com.github.llyb120.workflow.adapter.MemoryStorage;
import com.github.llyb120.workflow.adapter.StorageAdapter;
import com.github.llyb120.workflow.domain.dos.MayBeNextDo;
import com.github.llyb120.workflow.domain.dos.RoleDo;
import com.github.llyb120.workflow.domain.dos.UserDo;
import com.github.llyb120.workflow.domain.dos.UserRoleDo;
import com.github.llyb120.workflow.domain.dtos.MayBeNextDto;
import com.github.llyb120.workflow.entity.ActionEnum;
import com.github.llyb120.workflow.entity.FlowData;
import ma.glasnost.orika.CustomMapper;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.junit.Test;

import javax.script.ScriptException;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.github.llyb120.json.Json.a;
import static com.github.llyb120.json.Json.o;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class FlowTEst {

    private DealerAdapter createDealer(){
        MemoryDealer dealer = new MemoryDealer();
        //user
        List<UserDo> userDos = new ArrayList<>();
        UserDo zhangsan = new UserDo();
        zhangsan.setId("1");
        zhangsan.setUserName("admin");
        zhangsan.setNickName("张三");
        userDos.add(zhangsan);
        UserDo lisi = new UserDo();
        lisi.setId("2");
        lisi.setUserName("李四");
        lisi.setNickName("李四");
        userDos.add(lisi);

        //role
        List<RoleDo> roleDoList = new ArrayList<>();
        RoleDo guanliyuan = new RoleDo();
        guanliyuan.setId("100");
        guanliyuan.setName("管理员");
        roleDoList.add(guanliyuan);
        RoleDo caozuoyuan = new RoleDo();
        caozuoyuan.setId("200");
        caozuoyuan.setName("操作员");
        roleDoList.add(caozuoyuan);

        //userrole
        List<UserRoleDo> userRoleDos = new ArrayList<>();
        UserRoleDo userRoleDo = new UserRoleDo();
        userRoleDo.setUserId(zhangsan.getId());
        userRoleDo.setRoleId(guanliyuan.getId());
        userRoleDos.add(userRoleDo);
        userRoleDo = new UserRoleDo();
        userRoleDo.setUserId(lisi.getId());
        userRoleDo.setRoleId(caozuoyuan.getId());
        userRoleDos.add(userRoleDo);
        dealer.init(
                userDos,
                roleDoList,
                a(),
                userRoleDos,
                a()
        );
        return dealer;
    }

    private PluginRunner createRunner(){
        PluginRunner runner = PluginRunner.builder()
                .pluginDir("D:\\work\\cal-engine\\target\\classes\\com\\github\\llyb120\\workflow\\plugin")
                .basePackage("com.github.llyb120.workflow.plugin")
                .inject(StorageAdapter.class, WorkflowHolder.storageAdapter = new MemoryStorage())
                .inject(DealerAdapter.class, WorkflowHolder.dealerAdapter = createDealer())
                .build();
        return runner;
    }

    private FlowData findFlowData(PluginRunner runner, String id){
        return runner.execute("/flow/find", id);
    }

    @Test
    public void flow0() throws ScriptException {
        PluginRunner runner = createRunner();
        FlowData data = runner.execute("/flow/publish", "1",  "flow0");
        data = runner.execute("/flow/find", o("dataId", data.getId()));
        runner.execute("/flow/submit", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o(), false);
        runner.execute("/flow/submit", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o(), true);
        data = runner.execute("/flow/find", o("dataId", data.getId()));
        runner.execute("/flow/submit", "1", data.getId(), data.findCurrentLeaves().get(0).getId(), o("意见", "同意"), true);

        data = runner.execute("/flow/find", o("dataId", data.getId()));
    }


    @Test
    public void flow1(){
        PluginRunner runner = createRunner();
        //管理员发布
        FlowData data = runner.execute("/flow/publish", "1",  "flow1");
        data = runner.execute("/flow/submit", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o(), true);
        //多经办人填写
        data = runner.execute("/flow/submit", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o("a", 1), false);
        data = runner.execute("/flow/submit", "2", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o("b", 2), false);
        System.out.println(data);
    }


    @Test
    public void flow2(){
        PluginRunner runner = createRunner();
        FlowData data = runner.execute("/flow/publish", "1", "flow2");
        List<MayBeNextDo> mayBeNextDos =  runner.execute("/flow/calculateNextNode", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o());
        data = runner.execute("/flow/submit", "1", data.getId(), data.getFlowDataLeaf().getIndexLeafId(), o(), true, convert(mayBeNextDos));
        assertEquals(2, data.findCurrentLeaves().size());
        //分别提交
        String leafId0 = data.findCurrentLeaves().get(0).getId();
        mayBeNextDos =  runner.execute("/flow/calculateNextNode", "1", data.getId(), leafId0, o());
        data = runner.execute("/flow/submit", "1", data.getId(), leafId0, o(), true, convert(mayBeNextDos));
    }


    private List<MayBeNextDto> convert(List<MayBeNextDo> mayBeNextDos){
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder()
                .build();
        mapperFactory.classMap(MayBeNextDo.class, MayBeNextDto.class)
                .byDefault()
                .customize(new CustomMapper<MayBeNextDo, MayBeNextDto>() {
                    @Override
                    public void mapAtoB(MayBeNextDo mayBeNextDo, MayBeNextDto mayBeNextDto, MappingContext context) {
                        mayBeNextDto.setHandlers(mayBeNextDo.getHandlers().stream().map(UserDo::getId).collect(Collectors.toList()));
                        super.mapAtoB(mayBeNextDo, mayBeNextDto, context);
                    }
                })
                .register();
        return mapperFactory.getMapperFacade().mapAsList(mayBeNextDos.toArray(), MayBeNextDto.class);
    }



    @Test
    public void t2(){
        System.out.println(ActionEnum.getValue(1));
    }


}
